package com.naiterui.ehp.bs.emr.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bp.utils.esign.ESignUtils;
import com.naiterui.ehp.bs.emr.dto.DoctorInfoDTO;
import com.naiterui.ehp.bs.emr.dto.MedicalRecordDTO;
import com.naiterui.ehp.bs.emr.dto.MedicalRecordDetailDTO;
import com.naiterui.ehp.bs.emr.dto.PatientInfoDTO;
import com.naiterui.ehp.bs.emr.dto.SignInfoDTO;
import com.naiterui.ehp.bs.emr.entity.mongo.DoctorInfo;
import com.naiterui.ehp.bs.emr.entity.mongo.ImgFile;
import com.naiterui.ehp.bs.emr.entity.mongo.MedicalRecord;
import com.naiterui.ehp.bs.emr.entity.mongo.SessionInfo;
import com.naiterui.ehp.bs.emr.repository.mongo.MedicalRecordRepository;
import com.naiterui.ehp.bs.emr.service.IMedicalRecordService;
import com.naiterui.ehp.bs.emr.utils.ImageUrlUtil;
import com.naiterui.ehp.bs.emr.vo.patient.MenstrualVO;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;


/**
 * @Description 病例数据对外统一业务接口实现
 * @Author gongbaoqiang
 * @Date 2019/11/27 10:47 AM
 */
@Slf4j
@Service
public class MedicalRecordServiceImpl implements IMedicalRecordService {

    @Autowired
    private MedicalRecordRepository medicalRecordRepository;


    @Override
    public PageVO<MedicalRecordDetailDTO> findByPatientId(Long patientId, Long inquirerId, PageParamVO pageParamVO)
            throws BusinessException {

        Page<MedicalRecord> page = medicalRecordRepository.findByInquirerIdAndSendAndCaseTypeNot(inquirerId, MedicalRecord.SEND_YES, MedicalRecord.CASETYPE_RECOM,
                pageParamVO.getPageable(Sort.by(Sort.Direction.DESC, "createAt")));
        List<MedicalRecordDetailDTO> list = page.getContent().stream()
                .map(s -> this.covertToDTO(s)).collect(Collectors.toList());

        return PageVO.newBuilder()
                     .pageNo(page.getNumber())
                     .pageSize(page.getSize())
                     .totalCount((int) page.getTotalElements())
                     .result(list)
                     .build();

    }

    @Override
    public MedicalRecordDetailDTO findById(String id) throws BusinessException {
        MedicalRecord record = medicalRecordRepository.get(id);
        return this.covertToDTO(record);
    }

    @Override
    public void addWhite(String caseId, DoctorInfoDTO doctor) throws BusinessException {
        MedicalRecord record = medicalRecordRepository.get(caseId);

        List<DoctorInfo> doctorInfos = record.getDoctors().stream().filter(s -> doctor.getDoctorId().equals(s.getDoctorId()))
                                             .collect(Collectors.toList());

        //医生信息不存在时，添加查看权限
        if (CollectionUtil.isEmpty(doctorInfos)) {
            DoctorInfo doctorInfo = new DoctorInfo();
            BeanUtil.copyProperties(doctor, doctorInfo);
            doctorInfo.setRole(DoctorInfo.ROLE_VIEWER);
            record.getDoctors().add(doctorInfo);
            medicalRecordRepository.update(record);
        }

    }

    @Override
    public PageVO<MedicalRecordDetailDTO> findPatientCaseByPatient(Long patientId, Pageable pageable)
            throws BusinessException {

        Page<MedicalRecord> page = medicalRecordRepository.findByPatientIdAndSendAndCaseTypeNot(patientId,
            MedicalRecord.SEND_YES, MedicalRecord.CASETYPE_RECOM, pageable);
        List<MedicalRecordDetailDTO> list = page.getContent().stream()
                .map(s -> this.covertToDTO(s)).collect(Collectors.toList());

        return PageVO.newBuilder()
                .pageNo(page.getNumber())
                .pageSize(page.getSize())
                .totalCount((int) page.getTotalElements())
                .result(list)
                .build();
    }

    @Override
    public List<MedicalRecordDetailDTO> findBySessionIds(List<String> sessionIds) {
        List<MedicalRecord> record = this.medicalRecordRepository.findBySessionIds(sessionIds);
        return record.stream().map(s -> this.covertToDTO(s)).collect(Collectors.toList());
    }

    @Override
    public List<MedicalRecordDetailDTO> findByIds(List<String> ids) {
        List<MedicalRecord> record = this.medicalRecordRepository.findAllByIdIn(ids);
        return record.stream().map(s -> this.covertToDTO(s)).collect(Collectors.toList());
    }

    /**
     * <pre>
     *     病例转dto
     * </pre>
     *
     * @param s
     * @return
     */
    private MedicalRecordDetailDTO covertToDTO(MedicalRecord s) {
        MedicalRecordDetailDTO dto = new MedicalRecordDetailDTO();
        dto.setId(s.getId());
        dto.setSessionId(Optional.ofNullable(s.getSessionInfo()).map(SessionInfo::getSessionId).orElse(null));
        dto.setDoctorName(s.getDoctorName());
        dto.setDepartmentName(s.getDepartment());
        dto.setHospitalName(s.getHospitalName());

        //患者信息
        PatientInfoDTO patient = new PatientInfoDTO();
        BeanUtil.copyProperties(s, patient);
        dto.setPatientInfo(patient);

        List<DoctorInfoDTO> doctors = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(s.getDoctors())) {
            doctors = s.getDoctors().stream().map(d -> {
                DoctorInfoDTO doctor = new DoctorInfoDTO();
                BeanUtil.copyProperties(d, doctor);
                return doctor;
            }).collect(Collectors.toList());
        } else {
            //兼容历史数据无此字段
            DoctorInfoDTO doctorInfo = new DoctorInfoDTO();
            BeanUtil.copyProperties(s, doctorInfo);
            doctorInfo.setRole(DoctorInfoDTO.ROLE_CREATER);
            doctors.add(doctorInfo);
        }
        //医生信息
        dto.setDoctors(doctors);

        //病例内容
        MedicalRecordDTO record = new MedicalRecordDTO();
        if (s.getRecordDoctor() != null) {
            BeanUtil.copyProperties(s.getRecordDoctor(), record);
            record.setMoreExamine(s.getRecordDoctor().getMoreExamin());
            if (null != s.getRecordDoctor().getMenstrual()) {
                MenstrualVO menstrual = new MenstrualVO();
                BeanUtil.copyProperties(s.getRecordDoctor().getMenstrual(), menstrual);
                record.setMenstrual(menstrual);
            }
            //病例图片
            if (CollectionUtil.isNotEmpty(s.getRecordDoctor().getImgList())) {
                record.setImgList(s.getRecordDoctor().getImgList().stream().map(img ->
                                                                                        ImgFile.builder()
                                                                                               .url(ImageUrlUtil.getMedicalRecordImg(img.getUrl()))
                                                                                               .uuid(img.getUuid())
                                                                                               .build()).collect(Collectors.toList()));
            }
            record.setMedicalRecordSettingList(s.getMedicalRecordSettingList());
        }
        dto.setRecord(record);

        //签名信息
        SignInfoDTO signInfo = new SignInfoDTO();
        if (s.getSignInfo() != null) {
            BeanUtil.copyProperties(s.getSignInfo(), signInfo);
            signInfo.setSealImage(ImageUrlUtil.getCaseImgDomain(s.getSignInfo().getSealImage()));
            signInfo.setHandWriting(ESignUtils.isHandWriting() ? SignInfoDTO.HANDWRITING_YES : SignInfoDTO.HANDWRITING_NO);
        }
        dto.setSignInfo(signInfo);
        //创建时间
        dto.setCreatedAt(s.getCreateAt());
        return dto;
    }
}
